home *** CD-ROM | disk | FTP | other *** search
/ No Fragments Archive 12: Textmags & Docs / nf_archive_12.iso / MAGS / SOURCES / ATARI_SRC.ZIP / atari source / HDX_BACK / HDX302.TT / HDX.C < prev    next >
Encoding:
C/C++ Source or Header  |  2001-02-09  |  34.5 KB  |  1,499 lines

  1. /* hdx.c */
  2.  
  3. /*
  4.  * Atari Hard Disk Installation Utility
  5.  * Copyright 1988 Atari Corp.
  6.  *
  7.  * Associated files
  8.  *    hdx.rsc        resource file
  9.  *    wincap        hard disk database (text file)
  10.  *
  11.  *    hdx.h        object tree definitions
  12.  *    defs.h        constant definitions
  13.  *    part.h        ST structure definitions
  14.  *    ipart.h        IBM structure definitions
  15.  *
  16.  *    hdx.c        top level, user interface (this file)
  17.  *    epart.c        edit partition sizes
  18.  *    fmt.c        disk formatting
  19.  *    part.c        partition reading/writing
  20.  *    sect.c        sector reading, writing, zeroing
  21.  *    string.c    string functions (matching, concat, ...)
  22.  *    assist.c    markbad(), zero()
  23.  *    wincap.c    hard disk parameter / partition size database
  24.  *    st.c        random ST functions (delay, reboot, ...)
  25.  *
  26.  *----
  27.  * 11-May-1988    ml.    Cleaned up the memory management in the program
  28.  *            (ie. for all files).  Memory chunks which are for
  29.  *            sure will be < 32k is allocated using malloc(),
  30.  *            whereas chunks >= 32k is allocated using Malloc().
  31.  *            When using malloc(), you will get the 'Stack Over-
  32.  *            flow message if you are in Supervisor mode and 
  33.  *            you have your own supervisor stack.  To get around
  34.  *            this, have to use mymalloc() (in mymalloc.s).
  35.  * 15-Mar-1988    ml.    Changed interface to Markbad.
  36.  * 11-Jan-1988    ml.    Modified dialogue boxes.
  37.  * 07-Dec-1987    ml.    Started to add in concept of Bad Sector List.
  38.  * ??-Oct-1987  ml.    Partition and Disk type menu now has 15 entries 
  39.  *            instead of 16.
  40.  * 30-Sep-1987    ml.    Inherited 'this' from Landon Dyer.
  41.  * 24-Mar-1986 lmd    Released to software test.
  42.  * 15-Mar-1986 lmd    Hacked up from earlier version by Jim Tittsler.
  43.  * 8-Nov-1988  jye. change or add some codes so that can be used for MS-DOS.
  44.  *
  45.  */
  46.  
  47. #include "obdefs.h"
  48. #include "gemdefs.h"
  49. #include "osbind.h"
  50. #include "defs.h"
  51. #include "part.h"
  52. #include "bsl.h"
  53. #include "hdx.h"
  54. #include "ipart.h"
  55. #include "addr.h"
  56. #include "error.h"
  57.  
  58. #define MFM 17
  59.  
  60. extern char sbuf[];
  61. extern int rebootp;
  62. extern long gbslsiz();
  63. extern long get3bytes();
  64. extern long bslsiz;
  65. extern BYTE *bsl;
  66. extern int uplim;            /* the number of partitions */
  67. extern long sptrk;
  68. extern long spcyl;
  69. extern int ibmpart;
  70. extern int yesscan;
  71. extern long disksiz;
  72. extern long ratio;
  73.  
  74. /* Globals */
  75. int rebootp = 0;    /* 1: must reboot (not return to desktop) */
  76. int format;        /* TRUE: just formatted disk */
  77. int running;        /* 1: continue evnt_multi() loop */
  78. char sbuf[512];        /* error message buffer */
  79. long extsiz;        /* the size of extened partition */
  80. long ostack;                /* old stack pointer */
  81. int toibm;            /* the flag of partition to ibm format */
  82. int ibm2st;            /* the flag for IBM partition to ST */
  83. long bps;            /* bytes per sector */
  84. int npart;            /* number of partition */
  85. int ext;            /* the index of extended partition */
  86. int extend;            /* the index of end extended partition */
  87. int showmany;        /* the flag that show the too much device alert box */
  88.  
  89. /*  Logical-to-dev+partition mapping table. */
  90. extern int nlogdevs;        /* #logical devs found */
  91. extern LOGMAP logmap[];        /* logical dev map */
  92. extern int livedevs[];        /* live physical dev flag */
  93.  
  94. /* Partition related variables */
  95. long maxpsiz = MAXPSIZ;
  96.  
  97. /* AES (windows and messages) related variables */
  98. int gl_hchar;        /* height of system font (pixels) */
  99. int gl_wchar;        /* width of system font (pixels) */
  100. int gl_wbox;        /* width of box able to hold system font */
  101. int gl_hbox;        /* height of box able to hold system font */
  102.  
  103. int phys_handle;    /* physical workstation handle */
  104. int handle;        /* virtual workstation handle */
  105. int wi_handle;        /* window handle */
  106.  
  107. int formw, formh, sx, sy, lx, ly;    /* dialogue box dimensions */
  108. int xdesk, ydesk, hdesk, wdesk;        /* window X, Y, width, height */
  109. int xwork, ywork, hwork, wwork;        /* desktop and work areas */
  110.  
  111. int msgbuff[8];        /* event message buffer */
  112. int keycode;        /* keycode returned by event-keyboard */
  113. int mx, my;        /* mouse x and y pos. */
  114. int butdown;        /* button state tested for, UP/DOWN */
  115. int ret;        /* dummy return variable */
  116. int pnf;        /* 1: partition or format; 0: zero or markbad */
  117.  
  118. int hidden;        /* current state of cursor */
  119.  
  120. int contrl[12];
  121. int intin[128];
  122. int ptsin[128];
  123. int intout[128];
  124. int ptsout[128];    /* storage wasted for idiotic bindings */
  125.  
  126. int work_in[11];    /* Input to GSX parameter array */
  127. int work_out[57];    /* Output from GSX parameter array */
  128. int pxyarray[10];    /* input point array */
  129.  
  130.  
  131.  
  132. /*
  133.  * Top level;
  134.  * we get control from the desktop.
  135.  */
  136. main()
  137. {
  138.     running = TRUE;
  139.     pnf = 0;        /* set the flag to it isn't partition yet */
  140.     appl_init();
  141.     phys_handle=graf_handle(&gl_wchar, &gl_hchar, &gl_wbox, &gl_hbox);
  142.     wind_get(0, WF_WORKXYWH, &xdesk, &ydesk, &wdesk, &hdesk);
  143.     open_vwork();
  144.     wi_handle=wind_create(0x0040&0x0080, xdesk, ydesk, wdesk, hdesk);
  145.  
  146.     hidden = FALSE;
  147.     butdown = TRUE;
  148.  
  149.     if (!rsrc_load(RESOURCEFILE)) {
  150.     errs("[2][|", RESOURCEFILE, "][ EXIT ]");
  151.     goto punt;
  152.     }
  153.  
  154.     
  155.     /* Get all addresses of dialogues from resource file */
  156.     if (getalladdr() != OK) {
  157.     errs("[2][|", RESOURCEFILE, "][ EXIT ]");
  158.     goto punt;
  159.     }
  160.  
  161.  
  162.     /*
  163.      * Get maximum partition size from
  164.      * wincap "@@" entry.
  165.      */
  166.     /*
  167.     if (wgetent("Parameters", "@@") == OK) {
  168.     if (wgetnum("ms", &maxpsiz) != OK)
  169.         maxpsiz = MAXPSIZ;
  170.     } else {
  171.         goto punt;
  172.     }
  173.     */
  174.  
  175.     ARROW_MOUSE;
  176.  
  177.     /* display menu bar */
  178.     menu_bar(menuobj, 1);
  179.  
  180.     while (running) {
  181.         domulti();
  182.     }
  183.  
  184.     /*
  185.      * If nothing has been done to the hard disks
  186.      * then just get out, back to the desktop.
  187.      * Otherwise reboot the system.
  188.      */
  189.     menu_bar(menuobj, 0);        /* erase menu bar */
  190.  
  191. punt:
  192.     /*
  193.      * If we have to reboot,
  194.      * tell the user and then do it.
  195.      *
  196.      */
  197.     if (rebootp) {
  198.     err(autoboot);
  199.     reboot();
  200.     }
  201.  
  202.     wind_delete(wi_handle);
  203.     v_clsvwk(handle);
  204.     appl_exit();
  205. }
  206.  
  207.  
  208. /*
  209.  * Get a single event, process it, and return.
  210.  *
  211.  */
  212. domulti(){
  213.     int event;
  214.     
  215.     event = evnt_multi(MU_MESAG,
  216.             1,1,butdown,
  217.             0,0,0,0,0,
  218.             0,0,0,0,0,
  219.             msgbuff,0,0,&mx,&my,&ret,&ret,&keycode,&ret);
  220.  
  221.     if (event & MU_MESAG) {
  222.         wind_update(TRUE);
  223.     switch (msgbuff[0]) {
  224.         case WM_REDRAW:
  225.         do_redraw(msgbuff[4],msgbuff[5],msgbuff[6],msgbuff[7]);
  226.         break;
  227.  
  228.         case MN_SELECTED:
  229.             BEE_MOUSE;
  230.         switch(msgbuff[3]) {
  231.             case MNDISK:
  232.             switch (msgbuff[4]) {
  233.                 case DIFORM:
  234.                     if (rescan(0,0) == ERROR)    {
  235.                         break;    /* don't report medium changed */
  236.                     }
  237.                     format = TRUE;
  238.                     dodiform();
  239.                     format = FALSE;
  240.                     break;
  241.                 case DIPART:
  242.                     if (rescan(0,0) == ERROR)    {
  243.                         break;    /* don't report medium changed */
  244.                     }
  245.                     dodipart(-1, NULL, NULL);
  246.                     break;
  247.                 case DIZERO:
  248.                     if (pnf)    {
  249.                         err(needboot);
  250.                     } else {
  251.                         if (rescan(0,1) == ERROR)    {
  252.                             break;    /* don't report medium changed */
  253.                         }
  254.                         dodizero();
  255.                     }
  256.                     break;
  257.                 case DIMARK:
  258.                     if (pnf)    {
  259.                         err(needboot);
  260.                     } else {
  261.                         if (rescan(0,1) == ERROR)    {
  262.                             break;    /* don't report medium changed */
  263.                         }
  264.                         dodimark();
  265.                     }
  266.                     break;
  267.                 case DISHIP:
  268.                     if (rescan(0,0) == ERROR)    {
  269.                         break;    /* don't report medium changed */
  270.                     }
  271.                     dodiship();
  272.                     break;
  273.                 default:        break;
  274.             }
  275.             break;
  276.  
  277.             case MNFILE:
  278.             switch (msgbuff[4]) {
  279.                 case FIQUIT:
  280.                 running = 0;
  281.                 break;
  282.  
  283.                 default:
  284.                 break;
  285.             }
  286.             break;
  287.             
  288.             case MNDESK:
  289.             if(msgbuff[4] == DEABOUT) {
  290.                 strcpy(abtdial[ABVERSN].ob_spec, "Version 3.02");
  291.                 abtdial[ABOK].ob_state = NORMAL;
  292.                 execform(abtdial);
  293.             }
  294.             break;        /* "cannot happen" */
  295.         }
  296.  
  297.         menu_tnormal(menuobj, msgbuff[3], 1);    /* back to normal */
  298.             ARROW_MOUSE;
  299.         break;
  300.         
  301.         case WM_NEWTOP:
  302.         case WM_TOPPED:
  303.         wind_set(wi_handle, WF_TOP, 0, 0, 0, 0);
  304.         break;
  305.  
  306.         case WM_CLOSED:
  307.         running = FALSE;
  308.         break;
  309.  
  310.         default:
  311.         break;
  312.     }
  313.     wind_update(FALSE);
  314.     }
  315. }
  316.  
  317.  
  318. /*
  319.  * Default partition name (no "pt" entry).
  320.  */
  321. #define    DEF_PARTNAME    "4-6-10"
  322.  
  323.  
  324. /*
  325.  * Map from button in format dial.
  326.  */
  327. int pfmt[] = {
  328.     PFMT0, PFMT1, PFMT2, PFMT3,
  329.     PFMT4, PFMT5, PFMT6, PFMT7,
  330.     PFMT8, PFMT9, PFMT10, PFMT11,
  331.     PFMT12, PFMT13, PFMT14
  332. };
  333.  
  334.  
  335. /*
  336.  * Handle [FORMAT] item.
  337.  *
  338.  */
  339. dodiform()
  340. {
  341.   extern char bootstop;
  342.   extern char bootend;
  343.   int dev, v, i, br;
  344.   int modesel;            /* flag for mode select */
  345.   long cnt, hdsiz;
  346.   char *s, *d, *wgetstr();
  347.   char bs[512], sendata[16];
  348.   char pnam[128];
  349.   char *seldev = "X", *id = "XXXXX";
  350.   HINFO hinfo;
  351.   char devnames[NAMSIZ];    /* device type name buffer */
  352.   long nbad;
  353.   extern long gbslsiz(), nument(), dsmarkbad();
  354.   long pattern, temp;
  355.   long longrandom();
  356.   char pr_id[5];    /* partition scheme id */
  357.   
  358.   /*
  359.    * Throw up generic formatting/partition warning,
  360.    * then get physical dev they want to clobber.
  361.    */
  362.   yesscan = 0;
  363.   fwarning[FWARNCN].ob_state = NORMAL;
  364.   fwarning[FWARNOK].ob_state = NORMAL;
  365.   if (execform(fwarning) != FWARNOK) return BAILOUT;
  366.  
  367.   if ((dev = gphysdev()) < 0) {
  368.       return BAILOUT;
  369.   }
  370.   strcpy(id, "mn");
  371.   br = 0;
  372.   
  373.   inqfmt:
  374.   /* Get all available disk types from wincap 'mn' entries */  
  375.   wallents(devnames, id);
  376.   
  377.   /* Shove format name text into buttons */
  378.   for (i = 0, s = devnames; i < 15 && *s; ++i) {
  379.       dsknames[pfmt[i]].ob_type = G_BUTTON;    /* button */
  380.       dsknames[pfmt[i]].ob_spec = (long)s;
  381.       dsknames[pfmt[i]].ob_state = NORMAL;
  382.       dsknames[pfmt[i]].ob_flags = SELECTABLE | RBUTTON;
  383.       while (*s++)
  384.     ;
  385.   }
  386.   
  387.   /* rest of buttons are invisible and untouchable */
  388.   for (; i < 15; ++i) {
  389.       dsknames[pfmt[i]].ob_type = G_IBOX;    /* invisible box */
  390.       dsknames[pfmt[i]].ob_spec = 0;        /* no thickness */
  391.       dsknames[pfmt[i]].ob_state = DISABLED;    /* nobody home */
  392.       dsknames[pfmt[i]].ob_flags = NONE;        /* disabled */
  393.   }
  394.   
  395.   /* clean up rest of the form and throw it up */
  396.   dsknames[PFOK].ob_state = NORMAL;
  397.   dsknames[PFCN].ob_state = NORMAL;
  398.   if (execform(dsknames) != PFOK)
  399.     return BAILOUT;
  400.   
  401.   /* search for format they picked */
  402.   for (i = 0; i < 15; ++i)
  403.     if (dsknames[pfmt[i]].ob_state & SELECTED)
  404.       break;
  405.   if (i >= 15) {        /* nothing picked */
  406.       return BAILOUT;
  407.   }
  408.   
  409.     if (!br)    {
  410.           if (wgetent(dsknames[pfmt[i]].ob_spec, "mn") == ERROR)    {
  411.             nofmt[NOSCHFMT].ob_spec = dsknames[pfmt[i]].ob_spec;
  412.             nofmt[NOSCHFMT].ob_state = NORMAL;
  413.             execform(nofmt, 0);
  414.             return ERROR;
  415.         }
  416.         if ((s = wgetstr("br")) != NULL)    {
  417.             strcpy(id, s);
  418.             br = 1;            /* processing the branch */
  419.             goto inqfmt;    /* start over */
  420.         }
  421.     }
  422.  
  423.     modesel = 1;
  424.   if (gfparm(&modesel, &hinfo, dsknames[pfmt[i]].ob_spec, id) != 0) {
  425.       return ERROR;
  426.   }
  427.   
  428.   /* get data pattern to test the disk */
  429.   if (wgetnum("dp", &pattern) != OK) {
  430.       pattern = longrandom();  /* can't find pattern from wincap, make one */
  431.   } else {
  432.       temp = pattern;
  433.       pattern <<= 16;    /* shift pattern to hi word */
  434.       pattern |= temp;
  435.   }
  436.  
  437.   /*
  438.    * One last chance to bail out.
  439.    */
  440.   *seldev = dev + '0';
  441.   (fmtfnl[FUNIT].ob_spec)->te_ptext = seldev;
  442.   fmtfnl[FMTYES].ob_state = NORMAL;
  443.   fmtfnl[FMTNO].ob_state = NORMAL;
  444.   if (execform(fmtfnl) != FMTYES) return BAILOUT;
  445.  
  446.   /* For REAL !! */  
  447.   dsplymsg(fmtmsg);
  448.  
  449.   bsl = 0L;
  450.   
  451.   /* Get size of Bad Sector List */
  452.   if ((bslsiz = gbslsiz(dev)) > 0L) {
  453.       /* Allocate memory for existing BSL */
  454.       if ((bsl = (BYTE *)mymalloc((int)bslsiz*512)) <= 0) {
  455.           ret = err(nomemory);
  456.           goto formend;
  457.       }
  458.       
  459.       /* Read in BSL */
  460.       if ((ret = rdbsl(dev)) != OK) {
  461.           /* Create a new BSL if current one is unusable */
  462.           if (creabsl(dev, NEW, 0L) != OK) {
  463.               ret = ERROR;
  464.               goto formend;
  465.           }
  466.       } else {
  467.             /* Remove USER BSL */
  468.             if (creabsl(dev, EXPAND, nument(VENDOR)) != OK) {
  469.                 ret = ERROR;
  470.                 goto formend;
  471.             }
  472.       }
  473.   } else if (bslsiz == 0L || bslsiz == ERROR) {    /* no bsl or read error */
  474.       if (creabsl(dev, NEW, 0L) != OK) {
  475.           ret = ERROR;
  476.           goto formend;
  477.       }
  478.   } else {    /* bslsiz == MDMERR; medium changed error */
  479.       ret = ERROR;
  480.       goto formend;
  481.   }
  482.   
  483.   /*
  484.    * In supervisor mode
  485.    * set disk format parameters
  486.    * and format the disk.
  487.    */
  488.   ostack = Super(NULL);
  489.   v = OK;                    /* assume everything is OK */
  490.   if (modesel)    {            /* normal mode select ? */
  491.       v = ms(dev, &hinfo);    /* Yes, do noprmal mode set */
  492.         /* Find formatted capacity of drive */
  493.       hdsiz = (long)hinfo.hi_cc * (long)hinfo.hi_dhc * (long)hinfo.hi_spt;
  494.   }    else {                    /* No, do special mode set */
  495.       if ((v = md_sense(dev, sendata)) == OK)        {
  496.         hdsiz = get3bytes(sendata+5);
  497.         v = sqms(dev, sendata);
  498.     }
  499.   }
  500.   disksiz = hdsiz;
  501.   delay();                    /* kludge delay */
  502.   if (v == OK)
  503.     v = doformat(dev, (UWORD)hinfo.hi_in);  /* format */
  504.   delay();                    /* kludge delay */
  505.   Super(ostack);
  506.   
  507.   if (v != 0) {
  508.       ret = errcode(dev);
  509.       if (tsterr(ret) != OK)
  510.           formaterr(dev);
  511.       ret = ERROR;
  512.       goto formend;
  513.   }
  514.   
  515.   ret = OK;
  516.   rebootp = 1;
  517. formend:
  518.   erasemsg();    /* Erase formatting box */
  519.   if (ret < 0) {
  520.       if (bsl > 0) free(bsl);
  521.       return ERROR;
  522.   }
  523.   
  524.   /*------------------------------------------*
  525.    * Markbad the device destructively.          *
  526.    * Bad Sectors found are added to the BSL.  *
  527.    * Write BSL to device.              *
  528.    *------------------------------------------*/
  529.   if ((nbad = dsmarkbad(dev, hdsiz, 1, pattern)) < 0) {
  530.       free(bsl);
  531.       return ERROR;
  532.   }
  533.   if (wrbsl(dev) != OK) {
  534.       free(bsl);
  535.       return ERROR;
  536.   }
  537.   free(bsl);
  538.  
  539.     
  540.   /*
  541.    * Install boot-stopper in sector image;
  542.    * write root sector to device.
  543.    * 6-13-88  Setting of soft format parameters in root sector sets
  544.    *        the hard disk size only.
  545.    */
  546.   fillbuf(bs, 512L, 0L);    /* create new root sector */
  547.   sbslparm(bs);            /* set BSL parameters */
  548.   if (modesel)    {
  549.       sfmtparm(bs, &hinfo);
  550.   } else {
  551.       sdisksiz(bs, disksiz);
  552.   }
  553.   for (d = bs, s = &bootstop, cnt = (long)(&bootend - &bootstop); --cnt;)
  554.     *d++ = *s++;
  555.   Protobt(bs, -1L, -1, 1);    /* make root sector executable */
  556.   
  557.   if ((ret = putroot(dev, bs, (SECTOR)0)) != OK) {
  558.       if (tsterr(ret) != OK)
  559.           err(rootwrit);
  560.       return ERROR;
  561.   }
  562.  
  563.   /*
  564.    * Make a copy of the default partition name.
  565.    * Figure out the partition scheme id.
  566.    */
  567.   if ((s = wgetstr("pt")) == NULL)
  568.     s = DEF_PARTNAME;
  569.   strcpy(pnam, s);
  570.   figprid(disksiz, pr_id);
  571.   dodipart(dev, pnam, pr_id);
  572.   return OK;
  573. }
  574.  
  575.  
  576.  
  577. /*
  578.  * Handle [PARTITION] item;
  579.  * if `xdev' is -1, throw up dialog boxes;
  580.  * if `xdev' >= 0, just partition the dev,
  581.  * using `pnam' as the partition type, 
  582.  * and `pr_id' to search for the type.
  583.  *
  584.  */
  585. dodipart(xdev, pnam, pr_id)
  586. int xdev;
  587. char *pnam;
  588. char *pr_id;
  589. {
  590.     int dev, i, ret =OK, fine;
  591.     int choice;
  592.     char *seldev = "X";
  593.     char *s;
  594.     char bs[512];
  595.     PART *pinfo;
  596.     int tem1, tem2;
  597.     long disksiz;
  598.     extern long getdsiz();
  599.  
  600.     if (xdev < 0) {
  601.     /*
  602.      * Throw up warning saying that partition is dangerous;
  603.      * then get physical dev they want to clobber.
  604.      */
  605.     pwarning[PWARNCN].ob_state = NORMAL;
  606.     pwarning[PWARNOK].ob_state = NORMAL;
  607.     if (execform(pwarning) != PWARNOK) return BAILOUT;
  608.     format = FALSE;
  609.     if ((dev = gphysdev()) < 0) {
  610.         return BAILOUT;
  611.     }
  612.     /*
  613.      * Let the user edit/pick partitions.
  614.      */
  615.     fine = 0;
  616.     while (!fine) {
  617.         if (sfigpart(bs, dev, (PART *)&pinfo) != OK)    {
  618.             if (pinfo > 0)    Mfree(pinfo);
  619.             return BAILOUT;
  620.         }
  621.         if ((ret = chkpart(dev, pinfo)) != OK) {
  622.             if (ret < 0)    {    /* size too big */
  623.                 err(nexsmem);
  624.             } else {    /* some other errors  */
  625.                 if (pinfo > 0)    Mfree(pinfo);
  626.                 return BAILOUT;
  627.             }
  628.         } else {
  629.             fine = 1;
  630.         }
  631.     }
  632.  
  633.     /* Last chance to bail out */
  634.     *seldev = dev + '0';
  635.     (partfnl[PUNIT].ob_spec)->te_ptext = seldev;
  636.     partfnl[PARTYES].ob_state = NORMAL;
  637.     partfnl[PARTNO].ob_state = NORMAL;
  638.     if (execform(partfnl) != PARTYES)    {
  639.         if (pinfo > 0)    Mfree(pinfo);
  640.         return BAILOUT;
  641.     }
  642.  
  643.     } else {
  644.         if (wgetent(pnam, pr_id) != OK) {
  645.             nopart[NOSCHPOK].ob_state = NORMAL;
  646.             (nopart[NOSCHPR].ob_spec)->te_ptext = pnam;
  647.             execform(nopart);
  648.             return ERROR;
  649.         }
  650.         npart = 4;
  651.         ext = NO_EXT;    /* set the extended partition flag to not exists */
  652.         dev = xdev;
  653.         if ((pinfo = (PART *)Malloc((long)sizeof(PART)*npart)) <= 0)    {
  654.             err(nomemory);
  655.             if (pinfo > 0)    Mfree(pinfo);
  656.             return ERROR;
  657.         }
  658.         inipart(pinfo, npart);
  659.         npart = 0;
  660.         for (i = 0; i < 4; ++i)
  661.             fillpart(i, &pinfo[i]);
  662.     }
  663.  
  664.     /* For REAL!! */
  665.     dsplymsg(partmsg);
  666.     
  667.     bsl = 0L;
  668.     
  669.     /* Get size of BSL */
  670.     if ((bslsiz = gbslsiz(dev)) > 0L) {
  671.         /* Allocate memory for existing BSL */
  672.         if ((bsl = (BYTE *)mymalloc((int)bslsiz*512)) <= 0) {
  673.             ret = err(nomemory);
  674.             goto partend;
  675.         }
  676.             
  677.         /* Read in BSL */
  678.         if ((ret = rdbsl(dev)) != OK) {
  679.             if (ret == INVALID)
  680.                 err(cruptbsl);
  681.             ret = ERROR;
  682.             goto partend;
  683.         }
  684.     } else if (bslsiz == 0) {
  685.         ret = err(oldfmt);
  686.         goto partend;
  687.     } else if (bslsiz == ERROR) {
  688.         ret = err(rootread);
  689.         goto partend;
  690.     } else {
  691.         ret = ERROR;
  692.         goto partend;
  693.     }
  694.  
  695.     
  696.     /* Lay out partition headers */
  697.     if (spheader(dev, &pinfo[0]) != OK) {
  698.         ret = ERROR;
  699.         goto partend;
  700.     }
  701.     
  702.     if (wrbsl(dev) != OK) {        /* write BSL */
  703.         ret = ERROR;
  704.         goto partend;
  705.     }
  706.  
  707.     /* check and change the structure's id after 'spheader()' */
  708.     changeid(pinfo);
  709.  
  710.     /* Shove partition parms into root sector */
  711.     if ((ret = getroot(dev, bs, (SECTOR)0)) != 0)    {
  712.         if (tsterr(ret) != OK)
  713.             err(rootread);
  714.         ret = ERROR;
  715.         goto partend;
  716.     }
  717.  
  718.     if ((ret = stlayroot(bs, dev, pinfo)) != OK)    {
  719.         goto partend;
  720.     }
  721.     tem1 = npart;            /* save the number of partitions */
  722.     tem2 = ext;                /* save the index of extended partition */
  723.     if (rescan(1,0)) {        /* has to be here because map changed    */
  724.         ret = ERROR;        /* after partitions are moved around,    */
  725.         goto partend;        /* report medium change error.        */
  726.     }
  727.     npart = tem1;
  728.     ext = tem2;
  729.     /* Partition the device with parameters given in pinfo */
  730.     if (stlaybs(dev, &pinfo[0]) != OK)
  731.         ret = ERROR;
  732.     else
  733.         ret = OK;
  734.         
  735.     rebootp = 1;
  736.     pnf = 1;        /* set the flag to just doing the partition */
  737. partend:
  738.     if (bsl > 0) free(bsl);
  739.     inipart(pinfo, npart);
  740.     if (pinfo > 0)    Mfree(pinfo);
  741.     erasemsg();
  742.     return (ret);
  743. }
  744.  
  745.  
  746. /*
  747.  * get root sector informations and write them into that sector 
  748.  */
  749.  
  750. stlayroot(bs, dev, part)
  751. char *bs;
  752. int dev;
  753. PART *part;
  754. {
  755.     int i;
  756.     UWORD sum = 0x1234;
  757.     long cnt, disksiz, prvst;
  758.     char *d, *s;
  759.     extern char bootstop;
  760.     extern char bootend;
  761.  
  762.     /* do the prime partition */
  763.     spart(bs, part, 0, &prvst);    /* set ST partition parameters */
  764.     /*
  765.       sfmtparm(bs, &hinfo);
  766.       for (d = bs, s = &bootstop, cnt = (long)(&bootend - &bootstop); --cnt;)
  767.         *d++ = *s++;
  768.     */
  769.     sbslparm(bs);                /* set bsl parameters */
  770.     Protobt(bs, -1L, -1, 1);        /* make root sector executable */
  771.     if ((ret = putroot(dev, bs, (SECTOR)0)) != OK) {
  772.         if (tsterr(ret) != OK)
  773.             err(rootwrit);
  774.         return(ERROR);
  775.     }
  776.     if (ext == NO_EXT)    return OK;        /* no extended partition */
  777.     /* do the extended partitions */
  778.     extsiz = part[ext].p_siz;
  779.     for (i = 4; i < npart; i++)    {
  780.         if (!(part[i].p_flg & P_EXISTS))    {     /* skip if not exists */
  781.             return OK;
  782.         }
  783.         spart(bs, part, i, &prvst);    /* set IBM partition parameters */
  784.         if ((ret = putroot(dev, bs, part[i].p_st)) != OK) {
  785.             if (tsterr(ret) != OK)
  786.                 err(rootwrit);
  787.             return(ERROR);
  788.         }
  789.     }
  790.     return OK;
  791. }
  792.  
  793.  
  794.  
  795.  
  796. /*
  797.  * Put information into the root structure
  798.  */
  799.  
  800. spart(image, pinfo, pnm, prvst)
  801.  
  802. char *image;            /* root sector buffer */
  803. register PART *pinfo;    /* partition information */
  804. int pnm;                /* partition number */
  805. long *prvst;            /* The previous partition start sector */
  806.  
  807. {
  808.     PART *rpart;
  809.     long numcyl;
  810.     int i, j;
  811.  
  812.     if (pnm)     {
  813.         fillbuf(image, 512L, 0L);
  814.     }
  815.     rpart = &((RSECT *)(image + 0x200 - sizeof(RSECT)))->hd_p[0];
  816.     if (pnm < 4)    {
  817.         for (i = 0; i < NPARTS; i++, rpart++)    {
  818.             if (pinfo->p_flg & P_EXISTS)    {
  819.                 rpart->p_flg = P_EXISTS;
  820.                 for (j = 0; j < 3; j++)
  821.                     rpart->p_id[j] = pinfo->p_id[j];
  822.                 rpart->p_st = pinfo->p_st;
  823.                 rpart->p_siz = pinfo->p_siz;
  824.             } else {
  825.                 rpart->p_flg = 0;
  826.                 for (j = 0; j < 3; j++)
  827.                     rpart->p_id[j] = 0;
  828.                 rpart->p_st = 0L;
  829.                 rpart->p_siz = 0L;
  830.             }
  831.             pinfo++;
  832.         }
  833.  
  834.     } else {    /* pnm => 4 */
  835.         rpart->p_flg = pinfo[pnm].p_flg;
  836.         for (j = 0; j < 3; j++)
  837.             rpart->p_id[j] = pinfo[pnm].p_id[j];
  838.         rpart->p_st = ROOTSECT;
  839.         rpart->p_siz = pinfo[pnm].p_siz - ROOTSECT;
  840.         rpart++;
  841.         if (((pnm + 1) != npart) && (pinfo[pnm+1].p_flg & P_EXISTS)) { 
  842.             /* need extened partition */
  843.             rpart->p_flg = P_EXISTS;
  844.             rpart->p_id[0] = 'X';
  845.             rpart->p_id[1] = 'G';
  846.             rpart->p_id[2] = 'M';
  847.             rpart->p_siz = pinfo[pnm+1].p_siz;
  848.             rpart->p_st = (pnm == 4) ? (pinfo[4].p_siz) :
  849.                                     (pinfo[pnm].p_siz + *prvst);
  850.             *prvst = rpart->p_st;
  851.         }
  852.  
  853.     }
  854. }
  855.  
  856.  
  857.  
  858. /*
  859.  * Setup partitions on the disk;
  860.  * write boot sectors and zero FATs and root directories.
  861.  *
  862.  */
  863. stlaybs(physdev, pinfo)
  864. int physdev;
  865. register PART *pinfo;
  866. {
  867.     int i, ldev, ret;
  868.     int kindfat;
  869.     SECTOR data, nsect;
  870.     char *devno="X";
  871.     long ndirs;
  872.     UWORD fatsiz;
  873.     BOOT *bs;
  874.     long serialno;
  875.     extern long longrandom();
  876.     extern long cell();
  877.     char *buf;
  878.     long size;
  879.  
  880.     if ((bslsiz = gbslsiz(physdev)) < 0L) {
  881.         if (bslsiz == ERROR)
  882.             err(rootread);
  883.         return ERROR;
  884.     }
  885.     /* SCAN_BS: pinfo is for scan() and laybs() use */
  886.     if (ext != NO_EXT)    sortpart(pinfo, SCAN_BS);    
  887.  
  888.     for (i = 0; i < npart; ++i, ++pinfo) {
  889.         
  890.         /* don't care if partition does not exist */
  891.         if (!(pinfo->p_flg & P_EXISTS)) {
  892.             return OK;
  893.         }
  894.  
  895.  
  896.     /*
  897.      * Compute boot sector parameters.
  898.      */
  899.         if (pinfo->p_siz > disksiz) {        /* partition >? disk size */
  900.             *devno = i + '0';
  901.             (part2big[BGPART].ob_spec)->te_ptext = devno;
  902.             part2big[BGPARTOK].ob_state = NORMAL;
  903.             execform(part2big);
  904.             return ERROR;
  905.         }
  906.  
  907.     /* estimat the bps */
  908.     /* MAXSECT = 16MB - 8 */
  909.     bps = cell((pinfo->p_siz-7)*BPS, (long)MAXSECT);
  910.  
  911.     /* the real bps */
  912.     bps = BPS * n2power((UWORD)cell(bps, (long)BPS));
  913.     ratio = bps / BPS;
  914.     nsect = pinfo->p_siz / ratio;
  915.  
  916.     size = (long)BPS * ratio;
  917.     if ((buf = (char *)Malloc(size)) <= 0)    {
  918.         err(nomemory);
  919.         if (buf > 0) Mfree((long)buf);
  920.         return ERROR;
  921.     }
  922.  
  923.     /*
  924.      * Install entries in boot sector image;
  925.      * force sector checksum to zero (non-executable);
  926.      * write boot sector to media.
  927.      *
  928.       *    512 bytes/sector
  929.      *    2 or 4 sectors/cluster (partition > 16Mb has 4 spc)
  930.      *    1 reserved sector (for boot)
  931.      *    2 FATs
  932.      *    ... dir slots
  933.      *    ... # sectors
  934.      *    F8 means media is a hard disk
  935.      *    ... FAT size
  936.      *
  937.      */
  938.      
  939.     /* Make a clean boot sector */
  940.     fillbuf(buf, bps, 0L);
  941.     bs = (BOOT *)buf;
  942.         
  943.  
  944.     /* bytes per sector */
  945.     iw((UWORD *)&bs->b_bps[0], (UWORD)bps);
  946.     
  947.     /* sectors per cluster */
  948.     bs->b_spc = SPC;
  949.         
  950.     /* number of reserved sectors */
  951.     iw((UWORD *)&bs->b_res[0], (UWORD)1);
  952.     
  953.     /* number of FATs */
  954.     bs->b_nfats = 2;
  955.     
  956.  
  957.     /*
  958.      * Compute root directory size
  959.      * 256 entries, plus fudge on devs > 10Mb
  960.      */
  961.     if (pinfo->p_siz < 0x5000L) ndirs = NUMEN;
  962.     else ndirs = nsect / 80;    /* 1 dir entry per 80 sectors */
  963.     /* round to nearest sector */
  964.     ndirs = (ndirs + ((UWORD)bps/BPDIR - 1)) & ~((UWORD)bps/BPDIR - 1);    
  965.     iw((UWORD *)&bs->b_ndirs[0], (UWORD)ndirs);
  966.     
  967.     /* number of sectors on media (partition) */
  968.     iw((UWORD *)&bs->b_nsects[0], (UWORD)nsect);
  969.  
  970.     /* media descriptor */
  971.     bs->b_media = 0xf8;
  972.  
  973.     /*--------------------------------------------------------------*
  974.      * Compute FAT size                        *
  975.      *                                *
  976.      * Num entries to map the entire partition            *
  977.      *    = partition's size in clusters                *
  978.      *    = partition's size in sectors / spc            *
  979.      *                                *
  980.      * Num entries in FAT                        *
  981.      *    = Num entries to map partition + reserved entries    *
  982.      *    = (partition's size in sectors / spc) + 2        *
  983.      *                                *
  984.      * Num sectors FAT occupies                    *
  985.      *    = Num entries in FAT / Num entries of FAT per sector    *
  986.      *    = Num entries in FAT / (512 / 2)    <16-bit FAT>    *
  987.      *    = ((partition's size in sectors / spc) + 2) / 256 + 1    *
  988.      *                        <+1 to round up>    *
  989.      *--------------------------------------------------------------*/
  990.     fatsiz = ((((nsect / bs->b_spc) + 2) * 2) / bps) + 1;
  991.     iw((UWORD *)&bs->b_spf[0], (UWORD)fatsiz);
  992.  
  993.     /* write the serial number to the bs */ 
  994.     Protobt(bs, 0x01000000, -1, -1);
  995.  
  996.     /*
  997.      * Write partition's boot sector
  998.      */
  999.     forcesum((UWORD *)buf, (UWORD)0);    /* force image checksum */
  1000.     if ((ret = wrsects(physdev,(UWORD)ratio,buf,(SECTOR)pinfo->p_st))!= OK) {
  1001.         if (tsterr(ret) != OK)
  1002.             err(bootwrit);
  1003.         return ERROR;
  1004.     }
  1005.  
  1006.     /*
  1007.      * Zero the partition
  1008.      */
  1009.     if ((ret = zerosect(physdev, (SECTOR)(pinfo->p_st+ratio),
  1010.              ((UWORD)((fatsiz*2 + ndirs*BPDIR/bps) * ratio)))) != OK) {
  1011.         if (tsterr(ret) != OK)
  1012.             err(hdrwrite);
  1013.         return ERROR;
  1014.     }
  1015.              
  1016.     /*
  1017.      * Make first 2 entries in FATs more IBM-like.
  1018.      */
  1019.     if ((ret = rdsects(physdev,(UWORD)ratio,buf,
  1020.                         (SECTOR)(pinfo->p_st+ratio)))!= 0){
  1021.         if (tsterr(ret) != OK)
  1022.             err(fatread);
  1023.         return ERROR;
  1024.     }
  1025.     *(UWORD *)&buf[0] = 0xf8ff;
  1026.     *(UWORD *)&buf[2] = 0xffff;
  1027.     if ((ret = wrsects(physdev,(UWORD)ratio,
  1028.                         buf,(SECTOR)(pinfo->p_st+ratio)))!= 0 ||
  1029.         (ret = wrsects(physdev,(UWORD)ratio,buf,
  1030.                         (SECTOR)(pinfo->p_st+ratio+fatsiz*ratio)))
  1031.         != 0) {
  1032.         if (tsterr(ret) != OK)
  1033.             err(fatwrite);
  1034.         return ERROR;
  1035.     }
  1036.  
  1037.     /*
  1038.      * Mark bad sectors recorded in the BSL into the FATs.
  1039.      * Calculating parameters:
  1040.      *    ldev - from physdev and i.
  1041.      *    fat0 - always equals 1.
  1042.      *    fatsiz - calculated above.
  1043.      *    data - starts after the boot sector, 2 FATs and rootdir.
  1044.      */
  1045.  
  1046.         if (bslsiz > 0) {
  1047.             if ((ldev = phys2log(physdev, i)) == ERROR)
  1048.                 return parterr(physdev);
  1049.             data = (SECTOR)1 + (SECTOR)(fatsiz*2) + (SECTOR)(ndirs*BPDIR/bps);
  1050.             bsl2fat(ldev, (SECTOR)ratio, (UWORD)(fatsiz*ratio), 
  1051.                                                 data*ratio, MEDIA);
  1052.         }
  1053.         if (buf > 0) Mfree((long)buf);
  1054.     }
  1055.     return OK;
  1056. }
  1057.  
  1058.  
  1059.  
  1060.  
  1061. /*
  1062.  * Handle [ZERO] item.
  1063.  *
  1064.  */
  1065. dodizero()
  1066. {
  1067.     int ldev, ret;
  1068.     char *seldev = "X";
  1069.     int i; 
  1070.  
  1071.     zwarning[ZWOK].ob_state = NORMAL;
  1072.     zwarning[ZWCN].ob_state = NORMAL;
  1073.     if (execform(zwarning) != ZWOK)
  1074.     return BAILOUT;
  1075.     if (showmany)    err(manyldev);
  1076.  
  1077.     if ((ldev = glogdev()) < 0) return BAILOUT;
  1078.  
  1079.     /* Find out if logical device has assumed parameters */
  1080.     if (chkparm(ldev) != OK) {
  1081.         wronparm[WRONOK].ob_state = NORMAL;
  1082.     execform(wronparm);
  1083.     return ERROR;
  1084.     }
  1085.         
  1086.     *seldev = ldev;
  1087.     (zerofnl[ZDRV].ob_spec)->te_ptext = seldev;
  1088.     strcat((zerofnl[ZDRV].ob_spec)->te_ptext, ":");
  1089.     zerofnl[ZYES].ob_state = NORMAL;
  1090.     zerofnl[ZNO].ob_state = NORMAL;
  1091.     if (execform(zerofnl) != ZYES)  return BAILOUT;
  1092.  
  1093.     dsplymsg(zeromsg);
  1094.     if (zero(ldev) == OK) {
  1095.     if (!rebootp) {
  1096.         for (i = 0; i < 10; i++) {
  1097.         if (!mediach(ldev-'A')) break;
  1098.         }
  1099.         if (i == 10) {
  1100.             rebootp = 1;
  1101.         err(mdach);
  1102.             }
  1103.     }
  1104.     }
  1105.     erasemsg();
  1106. }
  1107.  
  1108.  
  1109. /*
  1110.  * Handle [MARKBAD] item.
  1111.  *
  1112.  */
  1113. dodimark()
  1114. {
  1115.     int ldev, ret;
  1116.     int i;
  1117.  
  1118.     mwarning[MWARNOK].ob_state = NORMAL;
  1119.     mwarning[MWARNCN].ob_state = NORMAL;
  1120.     if (execform(mwarning) == MWARNCN)
  1121.         return BAILOUT;
  1122.     if (showmany)    err(manyldev);
  1123.  
  1124.     if ((ldev = glogdev()) < 0)
  1125.         return BAILOUT;
  1126.         
  1127.     /* Find out if logical device has assumed parameters */
  1128.     if (chkparm(ldev) != OK) {
  1129.         wronparm[WRONOK].ob_state = NORMAL;
  1130.     execform(wronparm);
  1131.     return ERROR;
  1132.     }
  1133.          
  1134.     dsplymsg(lmrkmsg);
  1135.     if (markbad(ldev) != OK) {
  1136.         erasemsg();
  1137.     } else {
  1138.         if (!rebootp) {
  1139.         for (i = 0; i < 10; i++) {
  1140.         if (!mediach(ldev-'A')) break;
  1141.         }
  1142.         if (i == 10) {
  1143.             rebootp = 1;
  1144.         err(mdach);
  1145.             }
  1146.         }
  1147.     }
  1148. }
  1149.  
  1150.  
  1151. /*
  1152.  * Map from button in ship dial.
  1153.  */
  1154. int sdev[] = {
  1155.     SDEV0, SDEV1, SDEV2, SDEV3,
  1156.     SDEV4, SDEV5, SDEV6, SDEV7
  1157. };
  1158.  
  1159. /*
  1160.  * Ship selected devices.
  1161.  */
  1162. dodiship()
  1163. {
  1164.   int i, seldev[8], selected=0;
  1165.   
  1166.     
  1167.   /* Throw up generic shipping warning. */
  1168.   shipdial[SWARNCN].ob_state = NORMAL;
  1169.   shipdial[SWARNOK].ob_state = NORMAL;
  1170.   if (execform(shipdial) != SWARNOK) return BAILOUT;
  1171.   
  1172.   /* Device(s) selected? */
  1173.   shipdev[SDEVOK].ob_state = NORMAL;
  1174.   shipdev[SDEVCN].ob_state = NORMAL;
  1175.   for(i = 0; i < MAXPHYSDEVS; i++) {    /* indicate what's alive */
  1176.         if (livedevs[i] == 0)
  1177.             shipdev[sdev[i]].ob_state = NORMAL;
  1178.         else
  1179.             shipdev[sdev[i]].ob_state = NORMAL | SHADOWED;
  1180.   }
  1181.   
  1182.   if (execform(shipdev) != SDEVOK)
  1183.       return BAILOUT;
  1184.       
  1185.   for(i = 0; i < MAXPHYSDEVS; i++) {    /* search for selected unit */
  1186.       if (shipdev[sdev[i]].ob_state & SELECTED) {
  1187.           seldev[i] = 1;
  1188.           selected++;
  1189.       } else {
  1190.             seldev[i] = 0;
  1191.       }
  1192.   }
  1193.   
  1194.   if (!selected) return BAILOUT;    /* nothing is selected */
  1195.   
  1196.   /* Throw up final shipping warning. */
  1197.   shipfnl[SFNLCN].ob_state = NORMAL;
  1198.   shipfnl[SFNLOK].ob_state = NORMAL;
  1199.   if (execform(shipfnl) != SFNLOK) return BAILOUT;
  1200.   
  1201.   /* For REAL!!! */
  1202.   /* Ship selected devices */
  1203.   for (i = 0; i < MAXPHYSDEV; i++) {
  1204.       if (seldev[i])
  1205.           ship(i);
  1206.   }
  1207.   
  1208.   /* Put out final message about turning off hard disks */
  1209.   scommand[TRNOFFOK].ob_state = NORMAL;
  1210.   execform(scommand);
  1211. }
  1212.  
  1213.  
  1214.  
  1215. /*
  1216.  * Translate unit number to tree index.
  1217.  *
  1218.  */
  1219. static int physxlat[] = {
  1220.     UNIT0, UNIT1, UNIT2, UNIT3,
  1221.     UNIT4, UNIT5, UNIT6, UNIT7
  1222. };
  1223.  
  1224.  
  1225. /*
  1226.  * Get physical device#,
  1227.  * return devno or -1.
  1228.  *
  1229.  */
  1230. gphysdev()
  1231. {
  1232.     int i, start;
  1233.  
  1234.     /*
  1235.      * Clean up and exec object;
  1236.      * shadow devs we KNOW are there.
  1237.      */
  1238.     physdial[PHYSOK].ob_state = NORMAL;
  1239.     physdial[PHYSCN].ob_state = NORMAL;
  1240.     
  1241.     if (format == TRUE) {
  1242.         start = 1;        /* start initializing at unit 0 */
  1243.     physdial[physxlat[0]].ob_state = NORMAL;
  1244.     } else {
  1245.         start = 0;        /* start initializing at unit 1 */
  1246.     }
  1247.     
  1248.     for (i = start; i < MAXPHYSDEVS; ++i)
  1249.     physdial[physxlat[i]].ob_state = DISABLED;
  1250.     for (i = 0; i < MAXPHYSDEVS; ++i)
  1251.     if (livedevs[i])
  1252.         physdial[physxlat[i]].ob_state = NORMAL | SHADOWED;
  1253.  
  1254.     if (execform(physdial) != PHYSOK)
  1255.     return ERROR;
  1256.      
  1257.     /* search for selected unit */
  1258.     for (i = 0; i < MAXPHYSDEVS; ++i)
  1259.     if (physdial[physxlat[i]].ob_state & SELECTED)
  1260.         return i;
  1261.  
  1262.     return ERROR;            /* if no object selected */
  1263. }
  1264.  
  1265.  
  1266. /*
  1267.  * Translate from logical device number
  1268.  * to object number in logical device
  1269.  * dialouge box.
  1270.  */
  1271. int logxlat[] = {
  1272.     CCOLON, DCOLON, ECOLON, FCOLON,
  1273.     GCOLON, HCOLON, ICOLON, JCOLON,
  1274.     KCOLON, LCOLON, MCOLON, NCOLON,
  1275.     OCOLON, PCOLON
  1276. };
  1277.  
  1278.  
  1279. /*
  1280.  * Get logical device,
  1281.  * return 'C'...'P'
  1282.  * or -1.
  1283.  *
  1284.  */
  1285. glogdev()
  1286. {
  1287.     int i, flg;
  1288.  
  1289.     /*
  1290.      * Setup tree; selectively enable drive buttons
  1291.      * and so on.
  1292.      */
  1293.     logdial[LOGOK].ob_state = NORMAL;
  1294.     logdial[LOGCN].ob_state = NORMAL;
  1295.     for (i = 0; i < MAXLOGDEVS; ++i) {
  1296.     if (logmap[i].lm_physdev < 0)
  1297.         flg = DISABLED;
  1298.         else flg = NORMAL;
  1299.     logdial[logxlat[i]].ob_state = flg;
  1300.     }
  1301.  
  1302.     if (execform(logdial) != LOGOK) return -1;
  1303.  
  1304.     for (i = 0; i < MAXLOGDEVS; ++i)
  1305.     if (logdial[logxlat[i]].ob_state & SELECTED)
  1306.         return i + 'C';
  1307.  
  1308.     return -1;
  1309. }
  1310.  
  1311.  
  1312. /*
  1313.  * Open virtual workstation.
  1314.  *
  1315.  */
  1316. open_vwork()
  1317. {
  1318.     int i;
  1319.  
  1320.     for (i = 0; i < 10;)
  1321.     work_in[i++] = 1;
  1322.     work_in[10] = 2;
  1323.     handle = phys_handle;
  1324.     v_opnvwk(work_in, &handle, work_out);
  1325. }
  1326.  
  1327.  
  1328. /*
  1329.  * Find and redraw all clipping rectangles
  1330.  *
  1331.  */
  1332. do_redraw(xc, yc, wc, hc)
  1333. int xc, yc, wc, hc;
  1334. {
  1335.     GRECT t1, t2;
  1336.     int temp[4];
  1337.  
  1338.     hide_mouse();
  1339.     t2.g_x=xc;
  1340.     t2.g_y=yc;
  1341.     t2.g_w=wc;
  1342.     t2.g_h=hc;
  1343.     vsf_interior(handle, 1);
  1344.     vsf_color(handle, 0);
  1345.     wind_get(wi_handle, WF_FIRSTXYWH, &t1.g_x, &t1.g_y, &t1.g_w, &t1.g_h);
  1346.     while (t1.g_w && t1.g_h) {
  1347.     if (rc_intersect(&t2, &t1)) {
  1348.         set_clip(t1.g_x, t1.g_y, t1.g_w, t1.g_h);
  1349.         temp[0] = xwork;
  1350.         temp[1] = ywork;
  1351.         temp[2] = xwork + wwork - 1;
  1352.         temp[3] = ywork + hwork - 1;
  1353.         v_bar(handle, temp);
  1354.     }
  1355.     wind_get(wi_handle, WF_NEXTXYWH, &t1.g_x, &t1.g_y, &t1.g_w, &t1.g_h);
  1356.     }
  1357.  
  1358.     show_mouse();
  1359. }
  1360.  
  1361.  
  1362. /*
  1363.  * Hide the mouse.
  1364.  *
  1365.  */
  1366. hide_mouse()
  1367. {
  1368.     if (!hidden) {
  1369.     graf_mouse(M_OFF, 0L);
  1370.     hidden = TRUE;
  1371.     }
  1372. }
  1373.  
  1374.  
  1375. /*
  1376.  * Show the mouse.
  1377.  *
  1378.  */
  1379. show_mouse() 
  1380. {
  1381.     if (hidden) {
  1382.     graf_mouse(M_ON, 0L);
  1383.     hidden = FALSE;
  1384.     }
  1385. }
  1386.  
  1387.  
  1388. /*
  1389.  * Set clipping rectangle.
  1390.  *
  1391.  */
  1392. set_clip(x, y, w, h)
  1393. int x, y, w, h;
  1394. {
  1395.     int clip[4];
  1396.  
  1397.     clip[0] = x;
  1398.     clip[1] = y;
  1399.     clip[2] = x + w;
  1400.     clip[3] = y + h;
  1401.     vs_clip(handle, 1, clip);
  1402. }
  1403.  
  1404.  
  1405. /*
  1406.  * "Execute" form,
  1407.  * return thingy that caused the exit.
  1408.  *
  1409.  */
  1410. execform(tree)
  1411. OBJECT tree[];
  1412. {
  1413.     int thingy;
  1414.  
  1415.     ARROW_MOUSE;
  1416.     dsplymsg(tree);
  1417.     thingy = form_do(tree, 0);
  1418.     erasemsg();
  1419.     BEE_MOUSE;
  1420.     return thingy;
  1421. }
  1422.  
  1423.  
  1424. /*
  1425.  *  Display a dialogue box on the screen.
  1426.  *    Input:
  1427.  *        tree - object tree for dialogue box to be displayed.
  1428.  *    Output:
  1429.  *        formw, formh, sx, sy, lx, ly - dimensions of box.
  1430.  */
  1431. dsplymsg(tree)
  1432. OBJECT *tree;
  1433. {
  1434.     form_center(tree,&lx, &ly, &formw, &formh);
  1435.  
  1436.     /*
  1437.     sx = lx + formw / 2;
  1438.     sy = ly + formh / 2;
  1439.     */
  1440.     
  1441.     form_dial(1, 0, 0, 0, 0, lx, ly, formw, formh);
  1442.     objc_draw(tree, 0, MAX_DEPTH, 0, 0, wdesk, hdesk);
  1443. }
  1444.  
  1445.  
  1446. /*
  1447.  *  Erase a dialogue box from the screen.
  1448.  *    Input:
  1449.  *        formw, formh, sx, sy, lx, ly - dimensions of box.
  1450.  */
  1451. erasemsg()
  1452. {
  1453.     form_dial(3, 0, 0, 0, 0, lx, ly, formw, formh);
  1454. }
  1455.  
  1456.  
  1457.  
  1458. /*
  1459.  *  Make a long (4-byte) random.
  1460.  */ 
  1461. long
  1462. longrandom()
  1463. {
  1464.     long pattern;
  1465.     
  1466.     pattern = Random();
  1467.     pattern <<= 16;
  1468.     pattern ^= Random();
  1469.     
  1470.     return (pattern);
  1471. }
  1472.  
  1473. changeid(part)
  1474. PART *part;
  1475. {
  1476.     int i;
  1477.     long psiz;
  1478.  
  1479.     for(i = 0; i < npart; i++)    {
  1480.         if (i == ext)    continue;
  1481.         if (!(part[i].p_flg & P_EXISTS)) return OK;
  1482.         if (i > 3)    {
  1483.             psiz = part[i].p_siz - ROOTSECT;
  1484.         } else {
  1485.             psiz = part[i].p_siz;
  1486.         }
  1487.         if (psiz < MB16)    {
  1488.             part[i].p_id[0] = 'G';
  1489.             part[i].p_id[1] = 'E';
  1490.             part[i].p_id[2] = 'M';
  1491.         } else {
  1492.             part[i].p_id[0] = 'B';
  1493.             part[i].p_id[1] = 'G';
  1494.             part[i].p_id[2] = 'M';
  1495.         }
  1496.     }
  1497. }
  1498.  
  1499.